using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Xml;

using OpenComposite.EII.Designer.Workflow.Forms;
using OpenComposite.EII.Forms;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.Repository;
using OpenComposite.Workflow;
using OpenComposite.Base.Collections;
using OpenComposite.Workflow.Extenders;

namespace OpenComposite.EII.Designer.Workflow
{

	internal sealed class WorkflowMenuCommandService : MenuCommandService
	{
		#region Initialization

		public WorkflowMenuCommandService(IServiceProvider serviceProvider, WorkflowLoader loader)
			: base(serviceProvider)
		{
			_loader = loader;
			_serviceProvider = serviceProvider;

			System.Resources.ResourceManager rmDesign =
				new System.Resources.ResourceManager(
					"System.Design",
					typeof(System.Windows.Forms.Design.ControlDesigner).Assembly);
			System.Resources.ResourceManager rmWFDesign =
				new System.Resources.ResourceManager(
					"System.Workflow.ComponentModel.Design.DesignerResources",
					typeof(WorkflowView).Assembly);

			_cut = rmDesign.GetString("ContextMenuCut", System.Globalization.CultureInfo.CurrentUICulture);
			_copy = rmDesign.GetString("ContextMenuCopy", System.Globalization.CultureInfo.CurrentUICulture);
			_paste = rmDesign.GetString("ContextMenuPaste", System.Globalization.CultureInfo.CurrentUICulture);
			_delete = rmDesign.GetString("ContextMenuDelete", System.Globalization.CultureInfo.CurrentUICulture);

			_bmpCut = new Bitmap(typeof(System.Windows.Forms.Form).Assembly.GetManifestResourceStream("System.Windows.Forms.cut.bmp"));
			_bmpCut.MakeTransparent(Color.Magenta);
			_bmpCopy = new Bitmap(typeof(System.Windows.Forms.Form).Assembly.GetManifestResourceStream("System.Windows.Forms.copy.bmp"));
			_bmpCopy.MakeTransparent(Color.Magenta);
			_bmpPaste = new Bitmap(typeof(System.Windows.Forms.Form).Assembly.GetManifestResourceStream("System.Windows.Forms.paste.bmp"));
			_bmpPaste.MakeTransparent(Color.Magenta);
			_bmpDelete = new Bitmap(typeof(System.Windows.Forms.Form).Assembly.GetManifestResourceStream("System.Windows.Forms.delete.bmp"));
			_bmpDelete.MakeTransparent(Color.Magenta);

			_bmpZoomIn = rmWFDesign.GetObject("ZoomIn") as Bitmap;
			_bmpZoomIn.MakeTransparent(Color.Magenta);
			_bmpZoomOut = rmWFDesign.GetObject("ZoomOut") as Bitmap;
			_bmpZoomOut.MakeTransparent(Color.Magenta);
			_bmpPan = rmWFDesign.GetObject("PanOpenedHand") as Bitmap;
			_bmpPan.MakeTransparent(Color.Magenta);
			_bmpSelect = null;
		}

		#endregion Initialization

		#region Public Members

		#region Methods

		public override void ShowContextMenu(CommandID menuID, int x, int y)
		{
			ContextMenuStrip contextMenu = null;
			ICollection coll = this.GetCommandList(menuID.Guid);

			if ( menuID == WorkflowMenuCommands.DesignerActionsMenu ) {

				MenuCommand last = GetLast(coll);//Needed because of code in unmanaged part of VS.NET
				string err = last.Properties["Text"].ToString();
				DesignerAction da = last.Properties[new Guid("{3bd4a275-fccd-49f0-b617-765ce63b4340}")] as DesignerAction;
				ContextMenuStrip cms = new ContextMenuStrip();
				ToolStripMenuItem mi = new ToolStripMenuItem(err, null, new EventHandler(this.OnMenuClicked));
				if ( da != null ) mi.Image = da.Image;
				cms.Items.Add(mi);
				mi.Tag = last;
				last.Invoke();
				WorkflowView view1 = base.GetService(typeof(WorkflowView)) as WorkflowView;
				if ( view1 != null ) {
					EventHandler d = null;
					d = delegate(object o, EventArgs e)
					{
						cms.MouseLeave -= d;
						cms.Close();
					};
					cms.MouseLeave += d;
					cms.Show(view1, view1.PointToClient(new Point(x, y)));
				}
			} else if ( menuID == WorkflowMenuCommands.SelectionMenu ) {
				contextMenu = new ContextMenuStrip();

				foreach ( DesignerVerb verb in Verbs ) {
					addWorkflowMenuCommand(contextMenu, verb);
				}

				ToolStripItem[] items = GetSelectionMenuItems();
				if ( items.Length > 0 ) {
					contextMenu.Items.Add(new ToolStripSeparator());
					contextMenu.Items.AddRange(items);
				}

			} else if ( menuID == WorkflowMenuCommands.PageLayoutMenu ) {
				contextMenu = new ContextMenuStrip();
				// WorkflowMenuCommands.DefaultPage and WorkflowMenuCommands.PrintPreviewPage
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.DefaultPage, "Default View", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.PrintPreviewPage, "Print Preview", null);
			} else if ( menuID == WorkflowMenuCommands.ZoomMenu ) {
				contextMenu = new ContextMenuStrip();
				// WorkflowMenuCommands.Zoom400Mode, WorkflowMenuCommands.Zoom300Mode,
				// WorkflowMenuCommands.Zoom200Mode, WorkflowMenuCommands.Zoom150Mode,
				// WorkflowMenuCommands.Zoom100Mode, WorkflowMenuCommands.Zoom75Mode,
				// WorkflowMenuCommands.Zoom50Mode, WorkflowMenuCommands.ShowAll
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom400Mode, "400%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom300Mode, "300%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom200Mode, "200%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom150Mode, "150%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom100Mode, "100%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom75Mode, "75%", null);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Zoom50Mode, "50%", null);
				contextMenu.Items.Add(new ToolStripSeparator());
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.ShowAll, "Show All", null);
			} else if ( menuID == WorkflowMenuCommands.PanMenu ) {
				contextMenu = new ContextMenuStrip();
				// WorkflowMenuCommands.ZoomIn, WorkflowMenuCommands.ZoomOut, WorkflowMenuCommands.Pan,
				// WorkflowMenuCommands.DefaultFilter
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.ZoomIn, "Zoom In", _bmpZoomIn);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.ZoomOut, "Zoom Out", _bmpZoomOut);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.Pan, "Navigation Tool", _bmpPan);
				addWorkflowMenuCommand(contextMenu, WorkflowMenuCommands.DefaultFilter, "Default", _bmpSelect);
			}
			if ( contextMenu != null && contextMenu.Items.Count > 0 ) {
				WorkflowView workflowView = GetService(typeof(WorkflowView)) as WorkflowView;
				if ( workflowView != null )
					contextMenu.Show(workflowView, workflowView.PointToClient(new Point(x, y)));
			}
		}

		#endregion Methods

		#endregion Public Members

		#region Private Members

		#region Fields

		private WorkflowLoader _loader;
		private IServiceProvider _serviceProvider;

		private string _cut;
		private string _copy;
		private string _paste;
		private string _delete;

		private Bitmap _bmpCut;
		private Bitmap _bmpCopy;
		private Bitmap _bmpPaste;
		private Bitmap _bmpDelete;
		private Bitmap _bmpZoomIn;
		private Bitmap _bmpZoomOut;
		private Bitmap _bmpPan;
		private Bitmap _bmpSelect;

		#endregion Fields

		#region Event Handlers

		private void miAddDecisionBranch_Click(object sender, EventArgs e)
		{
			addDecisionBranch();
		}

		private void miAggregatorConfig_Click(object sender, EventArgs e)
		{
			configAggregator();
		}

		private void miAssignCapability_Click(object sender, EventArgs e)
		{
			assignCapability();
		}

		private void miAssignCompositeCapability_Click(object sender, EventArgs e)
		{
			assignCompositeCapability();
		}

		private void miConfigColumnMapper_Click(object sender, EventArgs e)
		{
			configColumnMapper();
		}

		//private void miConfigMSMQ_Click(object sender, EventArgs e)
		//{
		//    configMSMQ();
		//}

		private void miConfigNotification_Click(object sender, EventArgs e)
		{
			configNotification();
		}

		private void miCreateCompositeCapability_Click(object sender, EventArgs e)
		{
			createCompositeCapability();
		}

		private void miCreateNewCapability_Click(object sender, EventArgs e)
		{
			createNewCapability();
		}

		private void miHumanCapabilityConfiguration_Click(object sender, EventArgs e)
		{
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
			RepositoryService repSvc = GetService(typeof(RepositoryService)) as RepositoryService;
			LogicalCapabilityActivity humancap = getSelectedItem() as LogicalCapabilityActivity;
			if ( humancap != null ) {
				LogicalActivity logact = null;
				if ( humancap.LogicalActivityId == 0 ) {
					IRepositoryItem parentItem = null;
					logact = repSvc.GetNewItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, false,
											   ref parentItem) as LogicalActivity;
					logact.BeginEdit();
					try {
						logact.Name = humancap.Name;
						logact.Description = humancap.Description;
						logact.LogicalActivityType = LogicalActivityType.LogicalCapability;
					} finally {
						logact.EndEdit(true);
					}
					TypeDescriptor.GetProperties(humancap)["LogicalActivityId"]
						.SetValue(humancap, logact.ID);
					if ( !_loader.LogActIDs.Contains(logact.ID) ) _loader.LogActIDs.Add(logact.ID);
				} else {
					logact = repSvc.GetItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, humancap.LogicalActivityId, true) as LogicalActivity;
				}
				if ( logact != null ) {
					FormHumanTaskProperties frm = new FormHumanTaskProperties(logact, _loader.Workflow);
					frm.ShowDialog();
				}
			}
		}

		private void miLogicalActivityConfiguration_Click(object sender, EventArgs e)
		{
			configLogEPActivity();
		}

		private void miLogicalCapabilityConfiguration_Click(object sender, EventArgs e)
		{
			configLogCapability();
		}

		private void miRuleEvaluatorConfig_Click(object sender, EventArgs e)
		{
			configRuleEvaluator();
		}

		private void miSelectBusinessRule_Click(object sender, EventArgs e)
		{
			configBusinessRule();
		}

		private void miAssignCorrelationId_Click(object sender, EventArgs e)
		{
			assignCorrelationId();
		}

		#endregion Event Handlers

		#region Methods

		private MenuCommand GetLast(ICollection coll)
		{
			IEnumerator e = coll.GetEnumerator();
			MenuCommand last = null;
			while ( e.MoveNext() ) {
				last = e.Current as MenuCommand;
			}
			return last;
		}

		private ToolStripItem[] GetSelectionMenuItems()
		{
			List<ToolStripItem> menuItems = new List<ToolStripItem>();

			bool addMenuItems = true;
			bool addLogActMenuItems = false;
			bool addBRuleMenuItems = false;
			bool addAggregatorMenuItems = false;
			bool addLogCapMenuItems = false;
			bool addLogCapPropsMenuItems = false;
			bool addRuleEvalMenuItems = false;
			bool addCompositeCapMenuItems = false;
			//bool addDecisionMenuItems = false;
			bool addHumanCapMenuItems = false;
			bool addNotificationMenuItems = false;
			bool addAssignCapability = false;
			//bool addEndPointCapabilityItems = false;
			bool addColumnMapper = false;
			bool addMsmqItems = false;
			LogicalCapabilityType logActivityType = LogicalCapabilityType.LogicalCapability;
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			LogicalCapabilityActivity logAct = selectionService.PrimarySelection as LogicalCapabilityActivity;
			if ( selectionService != null ) {
				foreach ( object obj in selectionService.GetSelectedComponents() ) {
					if ( !( obj is Activity ) ) {
						addMenuItems = false;
						break;
					}
				}
				if ( selectionService.PrimarySelection is HorizontalSequenceActivity ||
					selectionService.PrimarySelection is SequentialWorkflowActivity ) {
					addAssignCapability = true;
				}
				if ( selectionService.PrimarySelection is LogicalEPActivity )
					addLogActMenuItems = true;
				if ( selectionService.PrimarySelection is LogicalCapabilityActivity ) {
					addLogCapMenuItems = true;

					logActivityType = logAct.Type;
					if ( logAct.LogicalActivityId > 0 ) {
						addLogCapPropsMenuItems = true;
					}
				}
				if ( selectionService.PrimarySelection is ColumnMapperActivity ) {
					addColumnMapper = true;
				}

				if ( selectionService.PrimarySelection is System.Workflow.Activities.IfElseBranchActivity ||
					 selectionService.PrimarySelection is System.Workflow.Activities.WhileActivity ||
					 selectionService.PrimarySelection is OpenComposite.Workflow.ConditionalBranchActivity ||
					 selectionService.PrimarySelection is OpenComposite.Workflow.HorizontalWhileActivity ||
					 selectionService.PrimarySelection is OpenComposite.Workflow.JumpSplitActivity )
					addBRuleMenuItems = true;
				else
					addBRuleMenuItems = false;

				if ( selectionService.PrimarySelection is DataAggregatorActivity )
					addAggregatorMenuItems = true;
				if ( selectionService.PrimarySelection is RuleEvaluatorActivity )
					addRuleEvalMenuItems = true;
				//if ( selectionService.PrimarySelection is DecisionActivity )
				//addDecisionMenuItems = true;
				if ( selectionService.PrimarySelection is CompositeCapabilityActivity )
					addCompositeCapMenuItems = true;
				if ( selectionService.PrimarySelection is HumanCapabilityActivity )
					addHumanCapMenuItems = true;
				if ( selectionService.PrimarySelection is LogicalCapabilityActivity ) {
				}
				if ( selectionService.PrimarySelection is NotificationActivity ) {
					addNotificationMenuItems = true;
				}
				//if ( selectionService.PrimarySelection is MsmqReceiveActivity ||
				//    selectionService.PrimarySelection is MsmqSendActivity ) {
				//    addMsmqItems = true;
				//}
				if ( logAct != null ) {
					LogicalActivity la = Global.Data.RepositoryService.GetItem<LogicalActivity>(logAct.LogicalActivityId);
					if ( la != null && la.LogicalMethod != null ) {
						if ( la.LogicalMethod.SendMessageQueue != null ||
							 la.LogicalMethod.ReceiveMessageQueue != null ) {
							addMsmqItems = true;
						}
					}
				}
			}

			if ( addAssignCapability ) {
				Bitmap verbicon = Resources.verb;
				verbicon.MakeTransparent(Color.Magenta);
				menuItems.Insert(0, new ToolStripMenuItem("Assign Exposed Capability...",
					verbicon, new EventHandler(miAssignCapability_Click)));
			}
			if ( addMenuItems ) {
				bool pasteAllowed = false;
				Activity[] acts = CompositeActivityDesigner.DeserializeActivitiesFromDataObject(_serviceProvider, Clipboard.GetDataObject());
				if ( acts != null && acts.Length > 0 ) pasteAllowed = true;
				Dictionary<CommandID, TextImage> selectionCommands = new Dictionary<CommandID, TextImage>();
				selectionCommands.Add(WorkflowMenuCommands.Cut, new TextImage(_cut, _bmpCut, true));
				selectionCommands.Add(WorkflowMenuCommands.Copy, new TextImage(_copy, _bmpCopy, true));
				selectionCommands.Add(WorkflowMenuCommands.Paste, new TextImage(_paste, _bmpPaste, pasteAllowed));
				selectionCommands.Add(WorkflowMenuCommands.Delete, new TextImage(_delete, _bmpDelete, true));

				foreach ( CommandID id in selectionCommands.Keys ) {
					MenuCommand command = FindCommand(id);
					if ( command != null ) {
						ToolStripMenuItem menuItem = new ToolStripMenuItem(
							selectionCommands[id].Text,
							selectionCommands[id].Image,
							new EventHandler(OnMenuClicked));
						menuItem.Tag = command;
						menuItem.Enabled = selectionCommands[id].Enabled;
						menuItem.Checked = command.Checked;
						menuItem.Visible = command.Visible;
						menuItems.Add(menuItem);
					}
				}
			}
			if ( addLogActMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Logical Operation Configuration...",
							  null, new EventHandler(miLogicalActivityConfiguration_Click)));
				menuItems.Insert(1, new ToolStripSeparator());
			}
			if ( addLogCapMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Assign Capability...",
							  null, new EventHandler(miAssignCapability_Click)));
				if ( addLogCapPropsMenuItems ) {
					menuItems.Insert(1, new ToolStripMenuItem("Logical Capability Properties...",
								  null, new EventHandler(miLogicalCapabilityConfiguration_Click)));
				} else {
					menuItems.Insert(1, new ToolStripMenuItem("Create New Capability...",
								  null, new EventHandler(miCreateNewCapability_Click)));
				}
				if ( addHumanCapMenuItems || logActivityType == LogicalCapabilityType.HumanActivityCapablity ) {
					menuItems.Insert(2, new ToolStripMenuItem("Human Capability Properties...",
								  Resources.png_user, new EventHandler(miHumanCapabilityConfiguration_Click)));
					menuItems.Insert(3, new ToolStripSeparator());
				} else {
					menuItems.Insert(2, new ToolStripSeparator());
				}

				ToolStripMenuItem convert = new ToolStripMenuItem("Convert to...");

				if ( logActivityType != LogicalCapabilityType.LogicalCapability ) {
					convert.DropDownItems.Add("...Logical Capability", null,
						new EventHandler(miConvertToLogicalCapability));
					convert.DropDownItems.Add(new ToolStripSeparator());
				}
				if ( logActivityType != LogicalCapabilityType.CompositeCapablity ) {
					convert.DropDownItems.Add("...Composite Capability", null,
							new EventHandler(miConvertToCompositeCapability));
				}
				if ( logActivityType != LogicalCapabilityType.HumanActivityCapablity ) {
					convert.DropDownItems.Add("...Human Activity Capability", null,
						new EventHandler(miConvertToHumanCapability));
				}

				menuItems.Add(new ToolStripSeparator());
				menuItems.Add(convert);
			}
			if ( addBRuleMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Select Rule...",
							  Resources.png_brule, new EventHandler(miSelectBusinessRule_Click)));
				menuItems.Insert(1, new ToolStripSeparator());
			}
			if ( addAggregatorMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Aggregator Configuration...",
							  null, new EventHandler(miAggregatorConfig_Click)));
				menuItems.Insert(1, new ToolStripSeparator());
			}
			if ( addRuleEvalMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Evaluator Configuration...",
							  Resources.png_brule, new EventHandler(miRuleEvaluatorConfig_Click)));
				menuItems.Insert(1, new ToolStripSeparator());
			}
			if ( addCompositeCapMenuItems || logActivityType == LogicalCapabilityType.CompositeCapablity ) {
				LogicalActivity la = Global.Data.RepositoryService.GetItem<LogicalActivity>(logAct.LogicalActivityId);
				if ( la == null || la.OperationID < 1 ) {
					menuItems.Insert(0, new ToolStripMenuItem("Assign Composite Workflow",
								Resources.png_capability, new EventHandler(miAssignCompositeCapability_Click)));
				} else {
					menuItems.Insert(0, new ToolStripMenuItem("Open Composite Workflow",
								Resources.png_capability, new EventHandler(miCreateCompositeCapability_Click)));
				}
				menuItems.Insert(1, new ToolStripSeparator());
			}

			if ( addNotificationMenuItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Configure Notification...",
							  null, new EventHandler(miConfigNotification_Click)));
			}
			if ( addColumnMapper ) {
				menuItems.Insert(0, new ToolStripMenuItem("Configure...",
					null, new EventHandler(miConfigColumnMapper_Click)));
			}
			if ( addMsmqItems ) {
				menuItems.Insert(0, new ToolStripMenuItem("Assign Correlation Id...",
					null, new EventHandler(miAssignCorrelationId_Click)));
			}

			return menuItems.ToArray();
		}

		private void OnMenuClicked(object sender, EventArgs e)
		{
			ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
			if ( menuItem != null && menuItem.Tag is MenuCommand ) {
				MenuCommand command = menuItem.Tag as MenuCommand;
				command.Invoke();
			}
		}

		private void addDecisionBranch()
		{
		}

		private void addWorkflowMenuCommand(ContextMenuStrip context, CommandID commandID,
			string text, Image icon)
		{
			MenuCommand com = this.FindCommand(commandID);
			ToolStripMenuItem item = new ToolStripMenuItem(text, icon, new EventHandler(OnMenuClicked));
			item.Enabled = com.Enabled;
			item.Visible = com.Visible;
			item.Checked = com.Checked;
			item.Tag = com;
			context.Items.Add(item);
		}

		private void addWorkflowMenuCommand(ContextMenuStrip context, DesignerVerb verb)
		{
			ToolStripMenuItem item = new ToolStripMenuItem(verb.Text, null, new EventHandler(OnMenuClicked));
			item.Enabled = verb.Enabled;
			item.Visible = verb.Visible;
			item.Checked = verb.Checked;
			item.Tag = verb;
			context.Items.Add(item);
		}

		private void assignCapability()
		{
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
			Activity act = getSelectedItem() as LogicalCapabilityActivity;
			RepositoryService repSvc = GetService(typeof(RepositoryService)) as RepositoryService;
			TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
			Verb assignedVerb = null;
			if ( act == null ) {
				act = getSelectedItem() as HorizontalSequenceActivity;
				if ( act == null ) {
					act = getSelectedItem() as SequentialWorkflowActivity;
					if ( act == null ) return;
				}
				assignedVerb = _loader.Workflow.Capability;
			} else {
				int logactid = (int)TypeDescriptor.GetProperties(act)["LogicalActivityId"].GetValue(act);
				if ( logactid > 0 ) {
					LogicalActivity la = repSvc.GetItem<LogicalActivity>(logactid);
					assignedVerb = la.Verb;
				}
			}

			using ( FormSelectRepositoryEx frm = new FormSelectRepositoryEx(_serviceProvider) ) {
				frm.DomainID = Global.Status.CurrentDomainId;
				frm.RepositoryID = Global.Status.CurrentRepositoryId;
				frm.AllowedTypes = new OpenComposite.EII.Repository.ItemType[] { OpenComposite.EII.Repository.ItemType.Verb };
				frm.MultiSelect = false;
				frm.SelectedItem = assignedVerb;
				if ( frm.ShowDialog() == DialogResult.OK ) {
					DesignerTransaction trans = designerHost.CreateTransaction();
					Verb v = frm.SelectedItem as Verb;
					if ( act is LogicalCapabilityActivity ) {
						if ( v != null ) {
							LogicalActivity la = v.AssignLogicalActivity(
								(int)TypeDescriptor.GetProperties(act)["LogicalActivityId"].GetValue(act));
							if ( la != null ) {
								la.LogicalActivityType = LogicalActivityType.LogicalCapability;
								la.Save();
								TypeDescriptor.GetProperties(act)["LogicalActivityId"].SetValue(act, la.ID);
								TypeDescriptor.GetProperties(act)["Capability"].SetValue(act, v.Name);
								if ( !_loader.LogActIDs.Contains(la.ID) )
									_loader.LogActIDs.Add(la.ID);
							}
							bool ok = false;
							int i = 0;
							string name = v.Name;
							do {
								try {
									TypeDescriptor.GetProperties(act)["Name"].SetValue(act, name);
									ok = true;
								} catch {
									i++;
									name = v.Name + i.ToString();
								}
							} while ( !ok );
						}
						( (IDesigner)designerHost.GetDesigner(act) ).Initialize(act);
					} else {
						_loader.Controller.Workflow.BeginEdit();
						if ( v != null ) {
							_loader.Controller.Workflow.StartName = v.Name;
							_loader.Controller.Workflow.StartDescription = v.Description;
							_loader.Controller.Workflow.InputBusinessObject = v.InputBusinessObject;
							_loader.Controller.Workflow.OutputBusinessObject = v.OutputBusinessObject;
							_loader.Controller.Workflow.ExtendedProperties.WorkflowCapabilityID = v.CapabilityID;
							_loader.Controller.Workflow.ExtendedProperties.WorkflowStartCapabilityMethodID = v.ID;
							#region Add Start Workflow Event
							IRepositoryItem parentItem = null;
							WorkflowEvent we = null;
							if ( _loader.Controller.Workflow.ExtendedProperties.StartEventID > 0 ) {
								we = repSvc.GetItem<WorkflowEvent>(_loader.Controller.Workflow.ExtendedProperties.StartEventID);
								if ( we.WorkflowID < 0 ) {
									we = repSvc.GetNewItem<WorkflowEvent>(false, ref parentItem);
									_loader.Controller.Workflow.ExtendedProperties.StartEventID = we.ID;
								}
							} else {
								we = repSvc.GetNewItem<WorkflowEvent>(false, ref parentItem);
								_loader.Controller.Workflow.ExtendedProperties.StartEventID = we.ID;
							}
							we.BeginEdit();
							we.Name = v.Name;
							we.Description = v.Description;
							we.IsStart = true;
							we.WorkflowID = _loader.Controller.Workflow.ID;
							we.BusinessObjectID = v.InputBusinessObjectID;
							we.EndEdit(true);
							if ( !_loader.Controller.Workflow.Interface.Events.Contains(we) ) {
								_loader.Controller.Workflow.Interface.Events.Add(we);
							}
							#endregion
							#region Add End Workflow Method
							WorkflowMethod wm = null;
							if ( v.OutputBusinessObject != null ) {
								parentItem = null;
								if ( _loader.Controller.Workflow.ExtendedProperties.ReplyMethodID > 0 ) {
									wm = repSvc.GetItem<WorkflowMethod>(_loader.Controller.Workflow.ExtendedProperties.ReplyMethodID);
									if ( wm.WorkflowID < 0 ) {
										wm = repSvc.GetNewItem<WorkflowMethod>(false, ref parentItem);
										_loader.Controller.Workflow.ExtendedProperties.ReplyMethodID = wm.ID;
									}
								} else {
									wm = repSvc.GetNewItem<WorkflowMethod>(false, ref parentItem);
									_loader.Controller.Workflow.ExtendedProperties.ReplyMethodID = wm.ID;
								}
								wm.BeginEdit();
								wm.Name = v.Name + OpenComposite.EII.CodeGenerators.Deployment.c_Reply;
								wm.Description = "This returns the output of this process to the process starter" +
									Environment.NewLine + v.Description;
								wm.WorkflowID = _loader.Controller.Workflow.ID;
								wm.InputBusinessObjectID = v.OutputBusinessObjectID;
								wm.EndEdit(true);
								if ( !_loader.Controller.Workflow.Interface.Methods.Contains(wm) ) {
									_loader.Controller.Workflow.Interface.Methods.Add(wm);
								}
							}
							#endregion
							_loader.Controller.Workflow.EndEdit(true);
							_loader.Controller.Save();
							_loader.Controller.WorkflowLoader.AddStartEndActivities(we, wm);
						} else {
							_loader.Controller.Workflow.StartName = "";
							_loader.Controller.Workflow.StartDescription = "";
							_loader.Controller.Workflow.InputBusinessObject = null;
							_loader.Controller.Workflow.OutputBusinessObject = null;
							_loader.Controller.Workflow.ExtendedProperties.WorkflowCapabilityID = -1;
							_loader.Controller.Workflow.ExtendedProperties.WorkflowStartCapabilityMethodID = -1;
							_loader.Controller.Workflow.EndEdit(true);
							_loader.Controller.Save();
						}
						_loader.Controller.WorkflowLoader.RefreshAllCode();
					}
					_loader.Controller.WorkflowView.PerformLayout(true);
					trans.Commit();
				}
			}
		}

		private void assignCompositeCapability()
		{
			LogicalCapabilityActivity act = getSelectedItem() as LogicalCapabilityActivity;
			if ( act == null ) return;

			LogicalActivity logAct = Global.Data.RepositoryService.GetItem<LogicalActivity>(act.LogicalActivityId);
			if ( logAct == null ) return;
			using ( FormSelectRepositoryEx form = new FormSelectRepositoryEx(_serviceProvider) ) {
				form.AllowedTypes = new ItemType[] { ItemType.Workflow, ItemType.Business_Process };
				form.MultiSelect = false;
				if ( form.ShowDialog() == DialogResult.OK ) {
					IRepositoryItem parent = null;
					Operation op = Global.Data.RepositoryService.GetNewItem<Operation>(false, ref parent);
					logAct.OperationID = op.ID;
					op.ExposedVerbID = logAct.VerbID;
					op.WorkflowId = _loader.Workflow.ID;
					op.ExposedWorkflowId = form.SelectedItem.ID;
					op.Name = logAct.Name;
					op.Save();
					logAct.Save();
				}
			}
		}

		private void configAggregator()
		{
			RepositoryService reps = _serviceProvider.GetService(typeof(RepositoryService)) as RepositoryService;
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;

			Debug.Assert(reps != null);
			Debug.Assert(designerHost != null);

			DataAggregatorActivity act = getSelectedItem() as DataAggregatorActivity;
			if ( act == null )
				return;
			LogicalActivity logact = null;
			try {
				logact = reps.GetItem(ItemType.LogicalActivity, act.LogicalActivityId, true) as LogicalActivity;
			} catch ( RepositoryItemDeletedException ) {
				logact = null;
			} catch ( Exception ex ) {
				MessageBox.Show(ex.Message, act.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			if ( logact == null || act.LogicalActivityId == 0 ) {
				IRepositoryItem parentItem = null;
				logact = reps.GetNewItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, false,
										 ref parentItem) as LogicalActivity;
				logact.BeginEdit();
				try {
					logact.Name = act.Name;
					logact.Description = act.Description;
					logact.LogicalActivityType = LogicalActivityType.DataAggregator;
				} finally {
					logact.EndEdit(true);
				}
				TypeDescriptor.GetProperties(act)["LogicalActivityId"].SetValue(act, logact.ID);
				if ( !_loader.LogActIDs.Contains(logact.ID) )
					_loader.LogActIDs.Add(logact.ID);
			} else {
				//logact = reps.GetItem(ItemType.LogicalActivity, act.LogicalActivityId, true) as LogicalActivity;
			}
			FormDataAggregatorConfiguration frm = new FormDataAggregatorConfiguration(_serviceProvider);
			frm.Init(logact.OutputBusinessObjectID);
			if ( frm.ShowDialog() == DialogResult.OK ) {
				DesignerTransaction trans = designerHost.CreateTransaction();
				logact.BeginEdit();
				try {
					string name = string.Format("Aggregate_{0}",
							frm.BusinessObject.Name.Trim().Replace(" ", "_"));
					name = WorkflowHelpers.EnsureUniqueName(act, name);
					TypeDescriptor.GetProperties(act)["Name"].SetValue(act, name);
					TypeDescriptor.GetProperties(act)["Text"]
						.SetValue(act, string.Format("Aggregate '{0}'", frm.BusinessObject.Name));
					TypeDescriptor.GetProperties(act)["LogicalActivityName"]
						.SetValue(act, string.Format("{0}{1}", act.Name, Guid.NewGuid().ToString("N")));
					TypeDescriptor.GetProperties(act)["LogicalActivityId"]
						.SetValue(act, logact.ID);
					TypeDescriptor.GetProperties(act)["OutputVarName"]
						.SetValue(act, string.Format("{0}_{1}", act.Name, frm.BusinessObject.Name));
					logact.OutputBusinessObjectID = frm.BusinessObject.ID;

					logact.Name = act.Name;
					logact.Description = act.Description;
					logact.LogicalActivityType = LogicalActivityType.DataAggregator;

					ActivityBind actbindIn = new ActivityBind(this._loader.ClassName, "LogicalActivitiesClass");
					act.SetBinding(DataAggregatorActivity.ActivitiesClassProperty, actbindIn);

					( (IDesigner)designerHost.GetDesigner(act) ).Initialize(act);

					logact.EndEdit(true);
					trans.Commit();
				} catch ( Exception ex ) {
					MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
					logact.CancelEdit();
					trans.Cancel();
				}
			}
		}

		private void configBusinessRule()
		{
			TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
			MemberCreationService memberCreation = GetService(typeof(IMemberCreationService)) as MemberCreationService;
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
			RepositoryService reps = _serviceProvider.GetService(typeof(RepositoryService)) as RepositoryService;

			if ( typeProvider == null )
				throw new NullReferenceException("TypeProvider missing.");
			if ( memberCreation == null )
				throw new NullReferenceException("MemberCreationService missing.");
			if ( designerHost == null )
				throw new NullReferenceException("IDesignerHost missing.");

			string name = "";
			object obj = getSelectedItem();
			IfElseBranchActivity actIfElse = obj as IfElseBranchActivity;
			ConditionalBranchActivity actHorizontal = obj as ConditionalBranchActivity;
			CompositeActivity actWhile = null;
			JumpSplitActivity actJump = obj as JumpSplitActivity;
			if ( obj is HorizontalWhileActivity )
				actWhile = obj as HorizontalWhileActivity;
			else if ( obj is WhileActivity )
				actWhile = obj as WhileActivity;

			if ( actIfElse == null && actWhile == null && actHorizontal == null && actJump == null )
				return;

			CompositeActivity rootActivity = ( (Activity)obj ).GetRootActivity() as CompositeActivity;

			if ( actIfElse != null )
				name = actIfElse.QualifiedName;
			else if ( actWhile != null )
				name = actWhile.QualifiedName;
			else if ( actHorizontal != null )
				name = actHorizontal.QualifiedName;
			else if ( actJump != null )
				name = actJump.QualifiedName;
			// set WorkflowConditionRuleAssignment
			Repository.Workflow.WorkflowConditionRuleAssignment wcra =
				this._loader.Workflow.ExtendedProperties.GetConditionAssignment(name);
			FormSelectBusinessRule frm = new FormSelectBusinessRule(_serviceProvider,
				typeProvider.GetType(_loader.FullClassName), _loader.Workflow);
			if ( wcra != null ) {
				// initialize FormSelectBusinessRule
				frm.Initialize(wcra.BusinessRuleId, wcra.ResultString);
			}
			if ( frm.ShowDialog() == DialogResult.OK ) {
				if ( frm.SelectedBusinessRule == null ) {
					return;
				}
				DesignerTransaction trans = designerHost.CreateTransaction();
				_loader.AddRuleToCode(frm.SelectedBusinessRule);
				if ( wcra != null && _loader.RuleIDs.Contains(wcra.BusinessRuleId) )
					_loader.RuleIDs.Remove(wcra.BusinessRuleId);
				if ( !_loader.RuleIDs.Contains(frm.SelectedBusinessRule.ID) )
					_loader.RuleIDs.Add(frm.SelectedBusinessRule.ID);
				_loader.Workflow.SetRuleIDs(_loader.RuleIDs);

				List<CodeExpression> lstRuleParams = new List<CodeExpression>();
				Dictionary<OpenComposite.EII.Repository.Workflow.RuleParameterResolve, CodeExpression> dicParams = frm.GetRuleParameterResolutionExpression();
				foreach ( KeyValuePair<OpenComposite.EII.Repository.Workflow.RuleParameterResolve, CodeExpression> val in dicParams ) {
					if ( val.Key == null || string.IsNullOrEmpty(val.Key.ParameterName) ) {
						continue;
					}
					memberCreation.CreatePropertyForRuleParameterResolution(
						_loader.FullClassName, val.Key.ParameterName,
						OpenComposite.EII.Helpers.GetDotNetTypeOfDataTypeString(val.Key.ParameterDataType),
						val.Value);
					lstRuleParams.Add(
						new CodePropertyReferenceExpression(
							new CodeThisReferenceExpression(),
							val.Key.ParameterName));
					if ( !_loader.Workflow.ExtendedProperties.WorkflowVariables.Contains(val.Key) )
						_loader.Workflow.ExtendedProperties.WorkflowVariables.Add(val.Key);
				}
				#region check that all workflow variables used in rules
				List<string> lstVarNms = new List<string>();
				foreach ( RepositoryBusinessRule rule in _loader.Workflow.GetRules() ) {
					Dictionary<string, string> parameters = rule.GetParameters();
					lstVarNms.AddRange(parameters.Keys);
				}
				Repository.Workflow.RuleParameterResolve[] rprs = _loader.Workflow.ExtendedProperties.WorkflowVariables.ToArray();
				foreach ( Repository.Workflow.RuleParameterResolve rpr in rprs ) {
					if ( !lstVarNms.Contains(rpr.ParameterName) )
						_loader.Workflow.ExtendedProperties.WorkflowVariables.Remove(rpr);
				}
				#endregion
				RuleDefinitions ruleDef = getRuleDefinitions();
				string ruleDefName = string.Format("{0}_{1}", frm.SelectedBusinessRule.Name, frm.SelectedResult);
				if ( !ruleDef.Conditions.Contains(ruleDefName) ) {
					ruleDef.Conditions.Add(
						new RuleExpressionCondition(
							ruleDefName,
							new CodeBinaryOperatorExpression(
								frm.GetRuleInvokationExpression(lstRuleParams),
								CodeBinaryOperatorType.ValueEquality,
								new CodePrimitiveExpression(frm.SelectedResult))));
					setRuleDefinitions(ruleDef);
				} else {
					( (RuleExpressionCondition)ruleDef.Conditions[ruleDefName] ).Expression =
							new CodeBinaryOperatorExpression(
								frm.GetRuleInvokationExpression(lstRuleParams),
								CodeBinaryOperatorType.ValueEquality,
								new CodePrimitiveExpression(frm.SelectedResult));
					setRuleDefinitions(ruleDef);
				}
				RuleConditionReference ruleCondRef = new RuleConditionReference();
				ruleCondRef.ConditionName = ruleDefName;
				string oldActName = null;
				if ( actIfElse != null ) {
					TypeDescriptor.GetProperties(actIfElse)["Condition"].SetValue(actIfElse, ruleCondRef);
					if ( !string.IsNullOrEmpty(frm.SelectedResult) ) {
						try {
							oldActName = actIfElse.Name;
							if ( frm.SelectedResult != oldActName ) {
								TypeDescriptor.GetProperties(actIfElse)["Name"]
																.SetValue(actIfElse, WorkflowHelpers.EnsureUniqueName(rootActivity, frm.SelectedResult));
							}
						} catch { }
					}
					name = actIfElse.Name;

					TypeDescriptor.GetProperties(actIfElse)["Description"]
						.SetValue(actIfElse, string.Format("IF {0} = {1}", frm.SelectedBusinessRule.Name, frm.SelectedResult));

					( (IDesigner)designerHost.GetDesigner(actIfElse) ).Initialize(actIfElse);
					Helpers.GetRootActivity(actIfElse).SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);
				} else if ( actWhile != null ) {
					TypeDescriptor.GetProperties(actWhile)["Condition"].SetValue(actWhile, ruleCondRef);
					if ( !string.IsNullOrEmpty(frm.SelectedResult) ) {
						try {
							oldActName = actWhile.Name;
							if ( frm.SelectedResult != oldActName ) {
								TypeDescriptor.GetProperties(actWhile)["Name"].SetValue(actWhile, WorkflowHelpers.EnsureUniqueName(rootActivity, frm.SelectedResult));
							}
						} catch { }
					}
					name = actWhile.Name;
					TypeDescriptor.GetProperties(actWhile)["Description"]
						.SetValue(actWhile, string.Format("WHILE {0} = {1}", frm.SelectedBusinessRule.Name, frm.SelectedResult));

					( (IDesigner)designerHost.GetDesigner(actWhile) ).Initialize(actWhile);

					Helpers.GetRootActivity(actWhile).SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);
				} else if ( actHorizontal != null ) {
					TypeDescriptor.GetProperties(actHorizontal)["Rule"].SetValue(actHorizontal, ruleCondRef);
					if ( !string.IsNullOrEmpty(frm.SelectedResult) ) {
						try {
							oldActName = actHorizontal.Name;
							if ( frm.SelectedResult != oldActName ) {
								TypeDescriptor.GetProperties(actHorizontal)["Name"].SetValue(actHorizontal, WorkflowHelpers.EnsureUniqueName(rootActivity, frm.SelectedResult));
							}
						} catch { }
					}
					name = actHorizontal.Name;
					TypeDescriptor.GetProperties(actHorizontal)["Description"]
						.SetValue(actHorizontal, string.Format("IF {0} = {1}", frm.SelectedBusinessRule.Name, frm.SelectedResult));

					( (IDesigner)designerHost.GetDesigner(actHorizontal) ).Initialize(actHorizontal);

					Helpers.GetRootActivity(actHorizontal).SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);
				} else if ( actJump != null ) {
					TypeDescriptor.GetProperties(actJump)["Condition"].SetValue(actJump, ruleCondRef);
					if ( !string.IsNullOrEmpty(frm.SelectedResult) ) {
						try {
							oldActName = actJump.Name;
							if ( frm.SelectedResult != oldActName ) {
								TypeDescriptor.GetProperties(actJump)["Name"].SetValue(actJump, WorkflowHelpers.EnsureUniqueName(rootActivity, frm.SelectedResult));
							}
						} catch { }
					}
					name = actJump.Name;
					TypeDescriptor.GetProperties(actJump)["Description"]
						.SetValue(actJump, string.Format("IF {0} = {1}", frm.SelectedBusinessRule.Name, frm.SelectedResult));

					( (IDesigner)designerHost.GetDesigner(actJump) ).Initialize(actJump);

					Helpers.GetRootActivity(actJump).SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);
				}
				OpenComposite.Workflow.Interfaces.ITextActivity textAct = obj as OpenComposite.Workflow.Interfaces.ITextActivity;
				if ( textAct != null && textAct is Activity ) {
					TypeDescriptor.GetProperties(textAct)["Text"]
						.SetValue(textAct, WorkflowHelpers.MakeNameWithSpaces(frm.SelectedResult));
				}
				trans.Commit();

				if ( wcra == null ) {
					// create new
					wcra = new OpenComposite.EII.Repository.Workflow.WorkflowConditionRuleAssignment();
					this._loader.Workflow.ExtendedProperties.WorkflowConditionRuleAssignments.Add(wcra);
				}
				wcra.ConditionActivityName = name;
				wcra.BusinessRuleId = frm.SelectedBusinessRule.ID;
				wcra.ResultString = frm.SelectedResult;
			}
		}

		private void configColumnMapper()
		{
			ColumnMapperActivity activity = getSelectedItem() as ColumnMapperActivity;
#if !DEBUG
			if ( activity.LogicalActivityId <= 0 ) {
				MessageBox.Show("The activity must subscribe to at least one document before it can be configured. " +
								"Please switch to the 'Subscriptions' tab in order to define the document subscriptions.", "Notification Configuration", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
#endif
			using ( FormColumnMapper form = new FormColumnMapper(activity) ) {
				form.ShowDialog();
			}
		}

		private void configLogCapability()
		{
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
			RepositoryService repSvc = GetService(typeof(RepositoryService)) as RepositoryService;
			LogicalCapabilityActivity logcap = getSelectedItem() as LogicalCapabilityActivity;
			if ( logcap != null ) {
				Repository.LogicalActivity logact = null;
				if ( logcap.LogicalActivityId == 0 ) {
					IRepositoryItem parentItem = null;
					logact = repSvc.GetNewItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, false,
											   ref parentItem) as Repository.LogicalActivity;
					logact.BeginEdit();
					try {
						logact.Name = logcap.Name;
						logact.Description = logcap.Description;
						logact.LogicalActivityType = LogicalActivityType.LogicalCapability;
					} finally {
						logact.EndEdit(true);
					}
					TypeDescriptor.GetProperties(logcap)["LogicalActivityId"].SetValue(logcap, logact.ID);
					if ( !_loader.LogActIDs.Contains(logact.ID) )
						_loader.LogActIDs.Add(logact.ID);
				} else {
					logact = repSvc.GetItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, logcap.LogicalActivityId, true) as Repository.LogicalActivity;
				}
				FormLogicalCapabilityConfiguration frm = new FormLogicalCapabilityConfiguration(_loader.Workflow);
				frm.Init(logcap.QualifiedName, logact);
				if ( frm.ShowDialog() == DialogResult.OK ) {
					DesignerTransaction trans = designerHost.CreateTransaction();
					logact.BeginEdit();
					try {
						ActivityBind actbindIn = new ActivityBind(this._loader.ClassName, "LogicalActivitiesClass");
						TypeDescriptor.GetProperties(logcap)["ActivitiesClass"]
							.SetValue(logcap, actbindIn);


						logact.Name = logcap.Name;
						logact.Description = logcap.Description;
						logact.LogicalActivityType = LogicalActivityType.LogicalCapability;
						( (IDesigner)designerHost.GetDesigner(logcap) ).Initialize(logcap);
					} finally {
						logact.EndEdit(true);
						trans.Commit();
					}
				} else {
					DesignerTransaction trans = designerHost.CreateTransaction();
					try {
						( (IDesigner)designerHost.GetDesigner(logcap) ).Initialize(logcap);
					} finally {
						trans.Commit();
					}
				}
			}
		}

		private void configLogEPActivity()
		{
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
			RepositoryService repSvc = GetService(typeof(RepositoryService)) as RepositoryService;
			LogicalEPActivity logop = getSelectedItem() as LogicalEPActivity;
			if ( logop != null ) {
				Repository.LogicalActivity logact = null;
				if ( logop.LogicalActivityId == 0 ) {
					IRepositoryItem parentItem = null;
					logact = repSvc.GetNewItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, false,
											   ref parentItem) as Repository.LogicalActivity;
					logact.BeginEdit();
					try {
						logact.Name = logop.Name;
						logact.Description = logop.Description;
						logact.LogicalActivityType = LogicalActivityType.LogicalOperation;
					} finally {
						logact.EndEdit(true);
					}
					TypeDescriptor.GetProperties(logop)["LogicalActivityId"].SetValue(logop, logact.ID);
					if ( !_loader.LogActIDs.Contains(logact.ID) )
						_loader.LogActIDs.Add(logact.ID);
				} else {
					logact = repSvc.GetItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, logop.LogicalActivityId, true) as Repository.LogicalActivity;
				}
				FormLogicalActivityConfiguration frm = new FormLogicalActivityConfiguration(_loader.Workflow);
				frm.Init(logop.QualifiedName, logact.OperationID,
						 logact.LogicalInputConnections, logact.PhysicalInputConnections,
						 logact.GetSubscribedBusinessObjects().BusinessObjects as IList<BusinessObject>);
				if ( frm.ShowDialog() == DialogResult.OK ) {
					DesignerTransaction trans = designerHost.CreateTransaction();
					logact.BeginEdit();
					try {
						if ( logop.Name.ToLower().StartsWith(logop.GetType().Name.ToLower()) ) {
							TypeDescriptor.GetProperties(logop)["Name"].SetValue(logop, frm.Operation.Name);
						}
						TypeDescriptor.GetProperties(logop)["LogicalActivityName"]
							.SetValue(logop, frm.Operation.Name.Replace(' ', '_'));

						ActivityBind actbindIn = new ActivityBind(this._loader.ClassName, "LogicalActivitiesClass");
						TypeDescriptor.GetProperties(logop)["ActivitiesClass"]
							.SetValue(logop, actbindIn);

						logact.OperationID = frm.Operation.ID;

						logact.Name = logop.Name;
						logact.Description = logop.Description;
						logact.LogicalActivityType = LogicalActivityType.LogicalOperation;

						( (IDesigner)designerHost.GetDesigner(logop) ).Initialize(logop);
					} finally {
						logact.EndEdit(true);
						trans.Commit();
					}
				} else {
					DesignerTransaction trans = designerHost.CreateTransaction();
					try {
						setSelectedItem(null);
						( (IDesigner)designerHost.GetDesigner(logop) ).Initialize(logop);
						designerHost.Container.Remove(logop);
						designerHost.Container.Add(logop, logop.QualifiedName);
						setSelectedItem(logop);
					} finally {
						trans.Commit();
					}
				}
			}
		}
		private void configNotification()
		{
			NotificationActivity activity = getSelectedItem() as NotificationActivity;
			if ( activity.LogicalActivityId <= 0 ) {
				MessageBox.Show("The notification object must subscribe to at least one document before it can be configured. " +
								"Please switch to the 'Subscriptions' tab in order to define the document subscriptions.", "Notification Configuration", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			using ( UIConfigXML form = new UIConfigXML(activity.Notification, _serviceProvider, activity.LogicalActivityId) ) {
				form.SmtpData = new OpenComposite.Mapper.ConfigSMTPInputData();
				form.SmtpData.SMTPUser = activity.NotificationUserName;
				form.SmtpData.SMTPSender = activity.NotificationSender;
				form.SmtpData.SMTPServer = activity.NotificationHost;
				form.SmtpData.SMTPPassword = activity.NotificationPassword;
				form.ActivityName = activity.Text;

				if ( form.ShowDialog() == DialogResult.OK ) {
					TypeDescriptor.GetProperties(activity)["Notification"].SetValue(activity, form.Notification);
					TypeDescriptor.GetProperties(activity)["NotificationHost"].SetValue(activity, form.SmtpData.SMTPServer);
					TypeDescriptor.GetProperties(activity)["NotificationUserName"].SetValue(activity, form.SmtpData.SMTPUser);
					TypeDescriptor.GetProperties(activity)["NotificationUserName"].SetValue(activity, form.SmtpData.SMTPUser);
					TypeDescriptor.GetProperties(activity)["NotificationPassword"].SetValue(activity, form.SmtpData.SMTPPassword);
				}
			}
		}

		private void configRuleEvaluator()
		{
			MemberCreationService memberCreation = GetService(typeof(IMemberCreationService)) as MemberCreationService;
			RepositoryService reps = _serviceProvider.GetService(typeof(RepositoryService)) as RepositoryService;
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;

			Debug.Assert(memberCreation != null);
			Debug.Assert(reps != null);
			Debug.Assert(designerHost != null);

			RuleEvaluatorActivity act = getSelectedItem() as RuleEvaluatorActivity;
			if ( act == null )
				return;
			LogicalActivity logact = null;
			if ( act.LogicalActivityId == 0 ) {
				IRepositoryItem parentItem = null;
				logact = reps.GetNewItem(OpenComposite.EII.Repository.ItemType.LogicalActivity, false,
										 ref parentItem) as Repository.LogicalActivity;
				logact.BeginEdit();
				try {
					logact.Name = act.Name;
					logact.Description = act.Description;
					logact.LogicalActivityType = LogicalActivityType.RuleEvaluator;
				} finally {
					logact.EndEdit(true);
				}
				TypeDescriptor.GetProperties(act)["LogicalActivityId"].SetValue(act, logact.ID);
				if ( !_loader.LogActIDs.Contains(logact.ID) )
					_loader.LogActIDs.Add(logact.ID);
			} else {
				logact = reps.GetItem(ItemType.LogicalActivity, act.LogicalActivityId, true) as LogicalActivity;
			}

			int oldbruleid = logact.BusinessRuleID;
			FormRuleEvaluatorConfiguration frm = new FormRuleEvaluatorConfiguration(_serviceProvider);
			frm.Init(logact.OutputBusinessObjectID, logact.BusinessRuleID, logact.ExtendedProperties.BusinessRuleOutputPath);
			if ( frm.ShowDialog() == DialogResult.OK ) {
				DesignerTransaction trans = designerHost.CreateTransaction();
				try {
					logact.BeginEdit();
					TypeDescriptor.GetProperties(act)["Name"]
						.SetValue(act, WorkflowHelpers.EnsureUniqueName(act, string.Format("Evaluate_{0}", frm.BusinessRule.Name)));
					TypeDescriptor.GetProperties(act)["Text"]
						.SetValue(act, string.Format("Evaluate '{0}'", frm.BusinessRule.Name));
					TypeDescriptor.GetProperties(act)["LogicalActivityName"]
						.SetValue(act, string.Format("EvaluateRule{0}", Guid.NewGuid().ToString("N")));
					logact.OutputBusinessObjectID = frm.BusinessObject.ID;
					logact.BusinessRuleID = frm.BusinessRule.ID;
					logact.ExtendedProperties.BusinessRuleOutputPath = frm.BusinessObjectPath;

					logact.Name = act.Name;
					if ( logact.OutputBusinessObject != null ) {
						act.SetValue(OutputVariableNameExtenderProvider.OutputVarNameProperty,
							string.Format("{0}_{1}", act.Name, logact.OutputBusinessObject.Name));
					}

					logact.Description = act.Description;
					logact.LogicalActivityType = LogicalActivityType.RuleEvaluator;

					ActivityBind actbindIn = new ActivityBind(this._loader.ClassName, "LogicalActivitiesClass");
					act.SetBinding(RuleEvaluatorActivity.ActivitiesClassProperty, actbindIn);

					_loader.AddRuleToCode(frm.BusinessRule);

					if ( oldbruleid != logact.BusinessRuleID && _loader.RuleIDs.Contains(oldbruleid) )
						_loader.RuleIDs.Remove(oldbruleid);
					if ( !_loader.RuleIDs.Contains(frm.BusinessRule.ID) )
						_loader.RuleIDs.Add(frm.BusinessRule.ID);
					_loader.Workflow.SetRuleIDs(_loader.RuleIDs);

					List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve> lstParams = frm.ParameterResolve;
					foreach ( OpenComposite.EII.Repository.Workflow.RuleParameterResolve rpr in lstParams ) {
						if ( !_loader.Workflow.ExtendedProperties.WorkflowVariables.Contains(rpr) )
							_loader.Workflow.ExtendedProperties.WorkflowVariables.Add(rpr);
					}

					( (IDesigner)designerHost.GetDesigner(act) ).Initialize(act);

					logact.EndEdit(true);
					trans.Commit();
				} catch ( Exception ex ) {
					MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
					logact.CancelEdit();
					trans.Cancel();
				}
			}
		}

		private void convertCapabilityTo(LogicalCapabilityType logicalCapabilityType)
		{
			IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			LogicalCapabilityActivity logAct = selectionService.PrimarySelection as LogicalCapabilityActivity;

			logAct.SetValue(LogicalCapabilityActivity.TypeProperty, logicalCapabilityType);
			host.GetDesigner(logAct).Initialize(logAct);
		}

		private void convertCapabilityTo(string target)
		{
			IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			LogicalCapabilityActivity logAct = selectionService.PrimarySelection as LogicalCapabilityActivity;
			LogicalCapabilityActivityDesigner designer = host.GetDesigner(logAct) as LogicalCapabilityActivityDesigner;
			HorizontalWorkflowDesigner root = WorkflowHelpers.GetRootDesigner(designer) as HorizontalWorkflowDesigner;
			switch ( target ) {
				case "code":
					break;
				default:
					break;
			}
		}

		private void convertDecisionTo(LogicalCapabilityType logicalCapabilityType)
		{
			IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			DecisionActivity decision = selectionService.PrimarySelection as DecisionActivity;
			DecisionDesigner designer = host.GetDesigner(decision) as DecisionDesigner;
			HorizontalWorkflowDesigner root = WorkflowHelpers.GetRootDesigner(designer) as HorizontalWorkflowDesigner;
			List<Activity> inList = new List<Activity>();
			LogicalCapabilityActivity logAct = new LogicalCapabilityActivity();
			inList.Add(logAct);
			HitTestInfo hti = root.HitTest(designer.Location);
			ReadOnlyCollection<Activity> roc = new ReadOnlyCollection<Activity>(inList);
			root.InsertActivities(hti, roc);
			logAct.Name = decision.Name;
			logAct.Description = decision.Description;
			logAct.Type = logicalCapabilityType;

			List<Activity> reList = new List<Activity>();
			reList.Add(decision);
			roc = new ReadOnlyCollection<Activity>(reList);
			root.RemoveActivities(roc);
		}

		private void createCompositeCapability()
		{
			LogicalCapabilityActivity act = getSelectedItem() as LogicalCapabilityActivity;
			if ( act == null ) return;
			if ( act.LogicalActivityId < 1 ) return;
			RepositoryService repSvc = Global.Data.RepositoryService;
			if ( repSvc == null ) return;
			IMainController mainController = (IMainController)GetService(typeof(IMainController));
			if ( mainController == null ) return;

			LogicalActivity logAct = repSvc.GetItem<LogicalActivity>(act.LogicalActivityId);
			Operation op = repSvc.GetItem<Operation>(logAct.OperationID);
			if ( op == null ) return;
			op.ExposedWorkflow.OpenDiagram(repSvc);
		}

		private void createNewCapability()
		{
			LogicalCapabilityActivity act = getSelectedItem() as LogicalCapabilityActivity;
			if ( act == null ) return;
			FormSelectRepositoryEx form = new FormSelectRepositoryEx(_serviceProvider);
			form.AllowChangeType = false;
			form.AllowCreateNewItem = true;
			form.AllowedTypes = new ItemType[] { ItemType.Composite };
			form.MultiSelect = false;
			if ( form.ShowDialog() == DialogResult.OK ) {
				IRepositoryItem parent = form.SelectedItem;
				Verb v = Global.Data.RepositoryService.GetNewItem<Verb>(false, ref parent);
				v.Name = WorkflowHelpers.CleanString(act.Text);
				parent = null;
				LogicalActivity logAct = Global.Data.RepositoryService.GetNewItem<LogicalActivity>(false, ref parent);
				logAct.Name = v.Name;
				logAct.Save();
				v.AssignLogicalActivity(logAct.ID);
				v.Save();
				TypeDescriptor.GetProperties(act)["LogicalActivityId"].SetValue(act, logAct.ID);
				TypeDescriptor.GetProperties(act)["LogicalActivityName"].SetValue(act, logAct.Name);
				TypeDescriptor.GetProperties(act)["Capability"].SetValue(act, v.Name);

			}
		}

		private void assignCorrelationId()
		{
			IDesignerHost designer = _serviceProvider.GetService<IDesignerHost>();
			if ( designer == null ) return;
			CompositeActivity root = designer.RootComponent as CompositeActivity;
			if ( root == null ) return;
			LogicalAsyncEndActivity act = getSelectedItem() as LogicalAsyncEndActivity;
			if ( act == null ) return;
			FormAssignCorrelationId form = new FormAssignCorrelationId(act, root.GetNestedActivities());
			form.SelectedCorrelationActivity = act.StartActivityName;
			if ( form.ShowDialog() == DialogResult.OK ) {
				TypeDescriptor.GetProperties(act)["CorrelationActivity"].SetValue(act, form.SelectedCorrelationActivity);
			}
		}

		private RuleDefinitions getRuleDefinitions()
		{
			RuleDefinitions ruleDef = null;
			using ( TextReader tr = _loader.GetFileReader(".rules") )
			using ( XmlTextReader xtr = new XmlTextReader(tr) ) {
				if ( tr == null ) {
					ruleDef = new RuleDefinitions();
				} else {
					WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
					ruleDef = serializer.Deserialize(xtr) as RuleDefinitions;
				}
			}
			if ( ruleDef == null ) ruleDef = new RuleDefinitions();
			return ruleDef;
		}

		private object getSelectedItem()
		{
			object selectedItem = null;
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			if ( selectionService != null ) {
				selectedItem = selectionService.PrimarySelection;
			}
			return selectedItem;
		}

		private string getUniqueActivityName(string newname, Activity currentActivity)
		{
			IIdentifierCreationService identCreate = (IIdentifierCreationService)GetService(typeof(IIdentifierCreationService));
			identCreate.ValidateIdentifier(currentActivity, newname);
			return newname;
		}

		[Obsolete]
		private void miConvertDecisionToEPWebService(object sender, EventArgs e)
		{
			convertDecisionTo(LogicalCapabilityType.EndPointWS);
		}

		[Obsolete]
		private void miConvertDecisionToExternalEPWebService(object sender, EventArgs e)
		{
			convertDecisionTo(LogicalCapabilityType.ExternalEndPointWS);
		}

		private void miConvertDecisionToSelector(object sender, EventArgs e)
		{
			convertDecisionTo(LogicalCapabilityType.Selector);
		}

		private void miConvertToCodeActivity(object sender, EventArgs e)
		{
			convertCapabilityTo("code");
		}

		private void miConvertToCompositeCapability(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.CompositeCapablity);
		}

		[Obsolete]
		private void miConvertToEPWebService(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.EndPointWS);
		}

		[Obsolete]
		private void miConvertToExternalEPWebService(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.ExternalEndPointWS);
		}

		private void miConvertToExternalWebService(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.ExternalAtomicWS);
		}

		private void miConvertToHumanCapability(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.HumanActivityCapablity);
		}

		private void miConvertToItSystem(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.ItSystem);
		}

		private void miConvertToLogicalCapability(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.LogicalCapability);
		}

		private void miConvertToSelector(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.Selector);
		}

		private void miConvertToWebService(object sender, EventArgs e)
		{
			convertCapabilityTo(LogicalCapabilityType.AtomicWS);
		}

		private void setRuleDefinitions(RuleDefinitions ruleDef)
		{
			using ( TextWriter tw = _loader.GetFileWriter(".rules") )
			using ( XmlTextWriter xtw = new XmlTextWriter(tw) ) {
				WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
				serializer.Serialize(xtw, ruleDef);
			}
		}

		private void setSelectedItem(object item)
		{
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			if ( selectionService != null ) {
				ArrayList al = new ArrayList();
				if ( item != null )
					al.Add(item);
				selectionService.SetSelectedComponents(al);
			}
		}

		#endregion Methods

		#endregion Private Members

		private class TextImage
		{
			public TextImage(string text, Image img, bool enabled)
			{
				this.Text = text;
				this.Image = img;
				this.Enabled = enabled;
			}
			public string Text { get; set; }
			public Image Image { get; set; }
			public bool Enabled { get; set; }
		}
	}
}
